require("Content")
require("Behavior")
require("Book")

Mind = class("Mind", Content)

---

function Mind:initialize(name, behaviorDescriptor, type)

	if not type 
	then
		type = "Mind"
	end
	
	Content.initialize(self, name, type)
	self:registerEntityType("Mind")
	
	self.sensibilities	= {}
	self.body 			= Body:new(name .. "Body")
	self.body.mind 		= self
	self.beliefs		= Book:new()
	
	if behaviorDescriptor
	then
		self.behavior = Behavior:new(behaviorDescriptor)
		self.behavior.mind = self
	else
		self.behavior = false
	end
end

---

function Mind:onBeat()

	if self.behavior
	then
		self.behavior:updateVariables()
	end
end

---

function Mind:onDiscoveredEvent(event)

	self:addBelief(event)
	
	
	-- check sensibilities
	
	local verb = event:getVerb()
	
	if self.sensibilities[verb]
	then
		for i, sensibility in ipairs(self.sensibilities[verb])
		do
			sensibility:onDiscoveredEvent(event)
		end
	end
end

---

function Mind:addBelief(belief, dontReact)

	if not belief.isSentence
	then
		belief = Sentence:new(belief)
	end
	
	self.beliefs:addSentence(belief)
	
	if 
		(not dontReact) and
		(not belief:getDirectObject().isEntity) and
		belief:getDirectObject().isSentence
	then
		self:onDiscoveredEvent(belief:getDirectObject())
	end
end

---

function Mind:addSensibility(sensibility)

	local verb = sensibility.cause:getVerb()
	
	if not self.sensibilities[verb]
	then
		self.sensibilities[verb] = {}
	end
	
	self.sensibilities[verb][#self.sensibilities[verb] + 1] = sensibility
end

---

function Mind:sensePossibleActions()

	self.body:sensePossibleActions()

	self.possibleActionDirectory = {}
	self.lockedActionDirectory = self.body.lockedActionDirectory

	
	-- filter and expand possible action directory
	
	for verb, possibleActionList in pairs(self.body.possibleActionDirectory)
	do
		local translationFunctionName = "translate" .. verb:sub(1, 1):upper() .. verb:sub(2)
		
		for i, possibleAction in ipairs(possibleActionList)
		do
			
			if self:isVariableExist(translationFunctionName)
			then
				local translatedActions = self[translationFunctionName](self, possibleAction)
				
				for j, translatedAction in ipairs(translatedActions)
				do
					local verb = translatedAction:getVerb()
					
					if not self.possibleActionDirectory[verb] 
					then
						self.possibleActionDirectory[verb] = {} 
					end
					
					self.possibleActionDirectory[verb]
						[#self.possibleActionDirectory[verb] + 1] = translatedAction
				end
			else
				if not self.possibleActionDirectory[verb]
				then
					self.possibleActionDirectory[verb] = {}
				end
				
				self.possibleActionDirectory[verb][#self.possibleActionDirectory[verb] + 1] = possibleAction
			end
		end
	end
end

---

function Mind:translateTalk(originalAction)

	
	local tellActions = {}

	for verb, beliefByVerb in pairs(self.beliefs.sentencesByVerbs)
	do
		for i, belief in ipairs(beliefByVerb)
		do
			local sentence = Sentence:new()
			
			sentence:setSubject(self.body)
			sentence:setVerb("tell")
			sentence:setIndirectObject(originalAction:getDirectObject().mind)
			sentence:setDirectObject(belief)
			
			tellActions[#tellActions + 1] = sentence
		end
	end
	
	return tellActions
end